home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-12-15 | 14.2 KB | 561 lines | [TEXT/EDIT] |
- ( STRUCTUREs 2.5 for the Macintosh MACH2 version 2.1 )
- ( Jan 3, 1987 by Waymen Askey )
- ( This MACH2 extension is released for the public good; however,
- for those planning commercial use of this code, please notify
- me so that I might know of its intended use.
-
- Waymen Askey
- P.O. Box 901
- Vista, Ca 92083
- also
- GEnie MACH2 RoundTable.)
-
- \ floating point parameters and arrays added by
- \ J. Langowski @ MacTutor
-
- only mac also sane also forth definitions
-
- ( VARIABLES used in STRUCTURE 2.5 )
- decimal
- variable current.template
- variable op.type
- variable A5offset ( holds the A5 offset to a structure )
-
- ( CODE word utilities used in STRUCTURE 2.5 )
- code var.link ( -- a | variable link pointer )
- lea $F7F8(A5),A0
- move.l A0,-(A6)
- rts
- end-code
-
- code a5@ ( -- a )
- move.l A5,-(A6)
- rts
- end-code mach
-
- code get.field ( a1 a2 -- a3 -1 or 0 | searches templates )
- ( a1=template, a2= pad, a3=field pointer, 0 if not found )
- move.l (A6)+,D2
- move.l (A6)+,D3
- moveq.l #0,D1
- moveq.l #0,D0
- @start movea.l D3,A1
- movea.l D2,A0
- move.b (A1)+,D1 ( link to next field )
- beq.s @end ( if link=0, field not found )
- move.b (A1),D0
- @loop cmpm.b (A1)+,(A0)+
- dbne D0,@loop
- beq.s @found
- add.l D1,D3 ( increment field pointer )
- bra.s @start
- @found movea.l D3,A1
- move.b 1(A1),D1 ( get string count )
- addq.w #2,D1
- btst #0,D1 ( test for odd count )
- beq.s @even
- addq.w #1,D1
- @even add.l D1,D3
- moveq.l #-1,D1
- move.l D3,-(A6)
- @end move.l D1,-(A6)
- rts
- end-code
-
- code >sr ( n -- | push value onto subroutine stack )
- move.l (A6)+,-(A7)
- rts
- end-code mach
-
- code sr> ( -- n | pop value from subroutine stack )
- move.l (A7)+,-(A6)
- rts
- end-code mach
-
- code sr@ ( -- n | copy value from subroutine stack )
- move.l (A7),-(A6)
- rts
- end-code mach
-
- ( Miscellaneous utility words used in STRUCTURE 2.5 )
- : >even ( a -- a' | word aligns address, i.e. rounds up to even)
- dup 1 and + ;
-
- : >odd ( a -- a' | odd aligns address, rounds up to odd )
- 1 or ;
-
- : needed ( n -- | checks for at least n items on stack )
- depth 1- > abort" Missing needed stack item(s)! " ;
-
- ( Brute-force machine code words )
- : ncode,
- ( n1...n -- | machine code defining word, stuffs n words )
- create dup needed dup 2* w,
- 0 do w, loop
- does> ( -- | compiles machine code )
- dup 2+ swap dup w@ +
- do i w@ w, -2 +loop ;
-
- hex
- ( define some machine code "stuff" words )
- 41ED 1 ncode, lea_d(a5),a0
- 4EBA 1 ncode, jsr_d(PC)
- 4EAD 1 ncode, jsr_d(A5)
- ( LEA and JSR also need a word of extension for displacement )
- 2D3C 1 ncode, move.l_#,-(A6) ( plus a long extension for # )
- 2D08 1 ncode, move.l_a0,-(a6)
- 4E75 1 ncode, rts,
- ( The following expect an address to be in A0 )
- 7000 1010 2D00 3 ncode, byte@
- 7000 3010 2D00 3 ncode, word@
- 2D10 1 ncode, long@
- 201E 1080 2 ncode, byte!
- 201E 3080 2 ncode, word!
- 209E 1 ncode, long!
- 5187 5587 2247 22d8 22d8 32d8 6 ncode, real@
- 2247 20d9 20d9 30d9 5087 5487 6 ncode, real!
- 201e e580 2d30 0000 4 ncode, array@
- 201e e580 219e 0000 4 ncode, array!
- 201e e380 4281 3230 0000 2d01 6 ncode, warray@
- 201e e380 221e 3181 0000 5 ncode, warray!
- decimal
-
- ( Dictionary header, name, and struct link words )
- : link>name ( lfa -- 'nf | 'nf points to the header length byte)
- 4 + ;
-
- : name.count ( 'nf -- 'nf+1 n | dictionary header name count)
- count 31 and ;
-
- : link>segment ( lfa -- 'sf | 'sf is the dictionary segment field address)
- link>name name.count + >even ;
-
- : link>parameter ( lfa -- 'pf | 'pf is the parameter field pointer)
- link>segment 2+ ;
-
- : link>struct ( lfa -- struct.fields )
- link>segment 4 + ;
-
- : jsr_d(PC), ( lfa -- | compiles PC relative JSR)
- jsr_d(PC)
- link>body here - w, ;
-
- : jsr_d(A5), ( lfa -- | compiles A5 relative JSR, i.e. jump table )
- jsr_d(A5)
- link>parameter w@ w, ;
-
- : struct.zero ( -- lfa | returns lfa of struct.zero )
- " struct.zero" find drop ;
-
- : nallot ( n -- | allots n bytes in name space )
- np +! ;
-
- : name, ( -- parses and compiles text into name space.)
- 32 word np @ over c@ 1+ dup >odd nallot cmove ;
-
- : nc, ( n -- | compiles byte into name space )
- np @ c! 1 nallot ;
-
- : nw, ( n -- | compiles word into name space )
- np @ w! 2 nallot ;
-
- : n, ( n -- | compiles long into name space )
- np @ ! 4 nallot ;
-
- ( TEMPLATE, STRUCTURE and field words )
- : struct.error ( -- )
- cr pad count type
- ." ? Error, unknown field or incomplete structure path! "
- abort ;
-
- global
- : template ( -- here 0 | begins TEMPLATE definition )
- create here 0 2 allot
- does> ( -- template.size )
- dup w@ swap 4 - body>link current.template ! ;
-
- : tend ( here n -- | (T)emplate(END) ends template definition )
- swap w! 0 nw, ;
-
- global
- : afield ( size op.type -- )
- create w, >even w,
- does> ( here Toffset -- here new.Toffset )
- ( Toffset means (T)emplate(OFFSET) )
- 2dup 2+ w@ + >sr
- w@ np @ >sr 1 nallot name,
- 0 nc, ( field type=0 ) nc, ( op.type )
- nw, ( Toffset ) np @ sr@ - sr> c! ( field link )
- sr> ;
-
- ( The following op.types are reserved and defined below )
- ( 06 byte, 12 word, 18 long, 24 string, 30 real, 36 struct,
- 42 array, 48 warray )
-
- ( size.in.bytes op.type AFIELD named.afield.type )
- 1 06 afield :byte
- 2 12 afield :word
- 4 18 afield :long
- 10 30 afield :real
-
- : :string ( here Toffset size -- here Toffset+size+1 )
- 3 needed 1+ over + >even swap np @ >sr 1 nallot name,
- 0 nc, ( field type=0 ) 24 nc, ( op.type=24)
- nw, ( Toffset ) np @ sr@ - sr> c! ( field link ) ;
-
- : :array ( here Toffset size -- here Toffset+size+1 )
- 3 needed 4* over + swap np @ >sr 1 nallot name,
- 0 nc, ( field type=0 ) 42 nc, ( op.type=42)
- nw, ( Toffset ) np @ sr@ - sr> c! ( field link ) ;
-
- : :warray ( here Toffset size -- here Toffset+size+1 )
- 3 needed 2* over + swap np @ >sr 1 nallot name,
- 0 nc, ( field type=0 ) 48 nc, ( op.type=48)
- nw, ( Toffset ) np @ sr@ - sr> c! ( field link ) ;
-
- : :struct ( here Toffset size -- here Toffset+size )
- 3 needed over + >even swap np @ >sr 1 nallot name,
- 06 nc, ( field type=06 ) 36 nc, ( op.type=36 )
- nw, ( Toffset )
- current.template @ struct.zero - n, ( template link )
- np @ sr@ - sr> c! ( field link ) ;
-
- : >pad ( a -- | moves string to pad )
- pad over c@ 1+ cmove ;
-
- : make.var.link { | name.pointer var.pointer vlink -- }
- np @ -> name.pointer var.link @ -> var.pointer
- name.pointer var.link !
- name.pointer var.pointer - -> vlink
- name.pointer dup 1 and + -> name.pointer
- vlink name.pointer !
- name.pointer 4 + np ! ;
-
- ( Decision table for field type decode )
- : do.afield ( ^field.type -- true )
- 1+ dup c@ op.type ! 1+ w@ A5offset +! -1 ;
-
- : do.bfield ( ^field.type -- new.template false )
- dup 1+ dup c@ op.type ! 1+ w@ A5offset +!
- 4 + @ struct.zero + link>struct 0 ;
-
- : rts rts, ; immediate
-
- ( DO.FIELD table entries decode field data )
- ( afield's are simple :BYTE, :WORD, :LONG, :STRING types )
- ( bfield's are :STRUCT fields )
-
- create do.field ( field_type table_offset/type )
- ] do.afield rts ( afield 0 )
- do.bfield rts ( bfield 6 )
- [ ( end of current table )
-
- global
- : make.struct ( template.link A5offset -- )
- ( This is the word which must resolve a structure reference. )
- A5offset ! ( A5 displacement for the struct )
- 36 op.type ! ( set default op.type to struct )
- struct.zero + link>struct ( template.address -- )
- begin
- 32 word >pad
- pad get.field
- if ( field found )
- dup c@ do.field + execute
- else ( field not found )
- pad find 1 =
- if
- link>body execute -1
- else
- struct.error
- then
- then
- until ;
-
- hex
- : structure
- ( n -- | creates structure alloting n bytes in variable space )
- 1 needed create immediate make.var.link
- -4 allot lea_d(a5),a0 vp @ w, ( variable-like beginning )
- move.l_#,-(A6) current.template @ struct.zero - ,
- move.l_#,-(A6) vp @ ,
- " make.struct" find drop dup link>segment w@ 0=
- if jsr_d(PC), else jsr_d(A5), then
- rts,
- vallot ;
- decimal
-
- ( STRUCTURE operators )
- : compileA5 ( -- | compiles A5 reference )
- lea_d(a5),a0 a5offset @ w, ;
-
- : pushA5 ( -- | executes A5 var reference )
- a5offset @ a5@ + ;
-
- : do.bit ( -- ) ( I'm lazy, define your own. W. Askey )
- cr ." BIT operations are yet undefined!" abort ;
-
- : do.struct ( -- ) ( Fetch/store doesn't make sense here. )
- cr ." STRUCTURE fetch/store operations are undefined! " abort ;
-
- : do.string ( -- ) ( If you wish, define your own. )
- cr ." STRING fetch/store operations are undefined! " abort ;
-
- : do.byte@ ( f -- )
- if
- compileA5 byte@
- else
- pushA5 c@
- then ;
-
- : do.word@ ( f -- )
- if
- compileA5 word@
- else
- pushA5 w@
- then ;
-
- : do.long@ ( f -- )
- if
- compileA5 long@
- else
- pushA5 @
- then ;
-
- : do.array@ ( idx f -- )
- if
- compileA5 array@
- else
- 4* pushA5 + @
- then ;
-
- : do.warray@ ( idx f -- )
- if
- compileA5 warray@
- else
- 2* pushA5 + w@
- then ;
-
- : do.real@ ( f -- )
- if
- compileA5 real@
- else
- pushA5 f@
- then ;
-
- ( Decision table for fetch )
- create op.table@ ( op.types are offsets into this table )
- ] do.bit rts ( op.type = 0 )
- do.byte@ rts ( " " = 6 )
- do.word@ rts ( " " = 12 )
- do.long@ rts ( " " = 18 etc, etc. )
- do.string rts
- do.real@ rts
- do.struct rts
- do.array@ rts
- do.warray@ rts
- [
-
- : do.byte! ( f -- )
- if
- compileA5 byte!
- else
- pushA5 c!
- then ;
-
- : do.word! ( f -- )
- if
- compileA5 word!
- else
- pushA5 w!
- then ;
-
- : do.long! ( f -- )
- if
- compileA5 long!
- else
- pushA5 !
- then ;
-
- : do.array! ( idx f -- )
- if
- compileA5 array!
- else
- 4* pushA5 + !
- then ;
-
- : do.warray! ( idx f -- )
- if
- compileA5 warray!
- else
- 2* pushA5 + w!
- then ;
-
- : do.real! ( f -- )
- if
- compileA5 real!
- else
- pushA5 f!
- then ;
-
- create op.table! ( decision table for store )
- ] do.bit rts
- do.byte! rts
- do.word! rts
- do.long! rts
- do.string rts
- do.real! rts
- do.struct rts
- do.array! rts
- do.warray! rts
- [
-
- : s^ ( -- a | returns pointer to structure field )
- ( ALL field types are allowed. i.e. strings, struct, etc. )
- state @
- if
- compileA5 move.l_a0,-(a6)
- else
- pushA5
- then ; immediate
-
- : s@ ( -- data | Fetch field contents, data type smart)
- state @
- op.type @ op.table@ + execute ; immediate
-
- : s! ( data -- | Store into field, data type smart)
- state @
- op.type @ op.table! + execute ; immediate
-
- : stype ( -- op.type | returns the op.type of a field )
- op.type @ state @
- if
- [compile] literal
- then ; immediate
-
-
- ( Examples of structure usage. Data Storage is limited to
- the approximately 32K global area referenced off of
- register A5 -- just as for regular MACH2 variables.
- Structure references have a REQUIRED syntax, it is best
- NOT to use any non-STRUCTURE Forth words when between field
- names in a structure calling sequence. That is, please end
- each structure reference prior to any DUP's, SWAP's, etc.
- The structure pointer operator -- S^ -- may be used at any
- place in the structure calling sequence. S^ will return the
- address of the field or structure itself. Structures MUST
- be terminated with a defined structure operator! The defined
- operators in this upload are S^, S@, S!, and STYPE.
- WARNING, if you forget to terminate a structure, no
- structure reference will be compiled and an error message MAY
- NOT be given. Remember also that field names ARE CASE
- SENSITIVE and LOCAL to the structure template. Last comment,
- structures MAY be nested to any level. )
-
- fp
-
- template Point
- :word x
- :word y
- tend
-
- template Rect
- :word top
- :word left
- :word bottom
- :word right
- tend ( TEND ends template definition )
-
- \ example for FP parameters
- template parameter
- 30 :string name
- :real value
- 30 :string unit
- tend
-
- template measurement
- :long date \ in internal Mac format
- 80 :string title
- 255 :string descriptor
- parameter :struct wavelength
- parameter :struct temperature
- parameter :struct angle
- 256 :array time
- 256 :array counts
- tend
-
- measurement structure curve1
-
- : testarray
- 100 0 do i 4* i curve1 time s! loop
- 100 0 do i curve1 time s@ . cr loop
- ;
-
- : .date ( DateTime DateForm ) { | [ 40 lallot ] mydate -- }
- 8 shift ^ mydate call IUDateString ^ mydate count type
- ;
-
- : read.int
- begin
- pad 1+ 80 expect span @ pad c! pad number? not while
- drop cr ." Illegal number [integer], reenter - "
- repeat
- ;
-
- : read.float
- begin
- pad 1+ 80 expect span @ pad c! pad fnumber? not while
- fdrop cr ." Illegal number [float], reenter - "
- repeat
- ;
-
- : setup.curve1 { | dattim -- }
- ^ dattim call readdatetime drop @
- cr ." Today is " 1 .date
- cr ." Setting up parameters for curve 1."
- dattim curve1 date s!
- " lambda" dup c@ 1+ curve1 wavelength name s^ swap cmove
- " T" dup c@ 1+ curve1 temperature name s^ swap cmove
- " delta" dup c@ 1+ curve1 angle name s^ swap cmove
- " [nm]" dup c@ 1+ curve1 wavelength unit s^ swap cmove
- " [K]" dup c@ 1+ curve1 temperature unit s^ swap cmove
- " [°]" dup c@ 1+ curve1 angle unit s^ swap cmove
- cr ." Title (one line) - " cr pad 80 expect
- span @ curve1 title s^ c!
- pad curve1 title s^ 1+ span @ cmove
- cr ." Description (one line) - " cr pad 80 expect
- span @ curve1 descriptor s^ c!
- pad curve1 descriptor s^ 1+ span @ cmove
- cr ." lambda [nm] - " read.float curve1 wavelength value s!
- cr ." T [K] - " read.float curve1 temperature value s!
- cr ." delta [°] - " read.float curve1 angle value s!
- \ example setup of 'measurement data'
- 20 0 do
- i i curve1 time s!
- i 100 * i curve1 counts s!
- loop
-
- cr ." End setup --- " cr
- ;
-
-
- : dump.curve1 { | [ 80 lallot ] mydate -- }
- cr ." Data taken on " curve1 date s@ 1 .date
- cr curve1 title s^ count type
- cr curve1 descriptor s^ count type
- cr curve1 wavelength name s^ count type ." = "
- curve1 wavelength value s@ f.
- curve1 wavelength unit s^ count type
- cr curve1 temperature name s^ count type ." = "
- curve1 temperature value s@ f.
- curve1 temperature unit s^ count type
- cr curve1 angle name s^ count type ." = "
- curve1 angle value s@ f.
- curve1 angle unit s^ count type
- cr ." data follows:"
- 20 0 do cr
- i curve1 time s@ . space
- i curve1 counts s@ .
- loop
- cr
- ;
-